package fft;
import java.math.MathContext.*;
import processing.core.PApplet;
import ddf.minim.analysis.*;
import ddf.minim.spi.*;
import ddf.minim.*;
import java.io.*;
/**
 *  @brief This class contains statistic analysis functions
 *  So far implemented: Cross-Correlation, Mean Squared Error
 *  @author Frequent Flyers
 */

public class StatAnalysis {
    //Our array
    double[] dataSeriesX;
    double[] dataSeriesY;
    double[] correlation;
    double[] frequencies;
    double[] dif;
    int SIZE; //Define the standard size
    //Modes
    boolean DEBUG = true;

    /**Constructor, accepts 2 arrays and calculates the size of the statistic analysis*/
    public StatAnalysis(double f[], double[] x, double[] y) {
        frequencies = f;
        dataSeriesX = x;
        dataSeriesY = y;

        //Check if they're both equal in length, else truncate to the lowest size
        //and compare those range of values instead
        if (dataSeriesX.length == dataSeriesY.length) {
            SIZE = dataSeriesX.length; //Doesn't matter which one we use, they're both the same size
        } else {
            if (dataSeriesX.length > dataSeriesY.length) {
                SIZE = dataSeriesY.length;
            } else if (dataSeriesX.length < dataSeriesY.length) {
                SIZE = dataSeriesX.length;
            }
        }
    }

    /**@brief Perform a cross correlation on the two results to see their similarities */
    /** Assume that both are roughly the same size */
    /** http://www.thefouriertransform.com/series/mse.php*/
    public void crossCorrelate() {
        System.out.println("Running Cross-correlation.");
        File file = new File("Correlation Results.txt");
        if (file.exists()) {
            file.delete();
        }

        double mx = 0;
        double my = 0;

        //Statistics test
        double total = 0;
        double stdDev = 0;
        int counter = 0;

        //Calculate the average of the 2 series
        for (int i = 0; i < SIZE; i++) {
            mx += dataSeriesX[i];
            mx += dataSeriesY[i];
        }

        mx /= SIZE;
        my /= SIZE;

        //Calculate the denominator
        double sx = 0;
        double sy = 0;
        for (int i = 0; i < SIZE; i++) {
            sx += (dataSeriesX[i] - mx) * (dataSeriesX[i] - mx);
            sy += (dataSeriesY[i] - my) * (dataSeriesY[i] - my);
        }

        double denom = Math.sqrt(sx * sy);

        //Calculate the correlation
        for (int i = -SIZE + 1; i < SIZE; i++) {
            double sxy = 0;

            for (int j = 0; j < SIZE; j++) {
                int k = j + i;
                while (k < 0) {
                    k += SIZE;
                }
                k %= SIZE;
                sxy += (dataSeriesX[j] - mx) * (dataSeriesY[k] - my);

//                if(k < 0 || k >= SIZE)
//                {
//                    continue;
//                }
//                else
//                {
//                    sxy += (dataSeriesX[j] - mx) * (dataSeriesY[k] - my);
//                }
            }

            double r = sxy / denom;
            total += r;
            counter = i;
            //System.out.println("i : " + i + " " + r);
            printToFile("Correlation Results", "i : " + i + " " + r);
        }
        Math.sqrt(total /= SIZE);
        System.out.println("Standard Deviation is: " + total);
        System.out.println("Done.");
    }

    /**Calculate the means-squared error between 2 given sets of values*/
    public void MeanSquaredAvg() {
        System.out.println("Running MSE");

        //If the file exists already, delete it
        File file = new File("MSE.txt");
        if (file.exists()) {
            file.delete();
        }
        double[] error = new double[SIZE];
        dif = new double[SIZE];
        double sum = 0;
        for (int i = 0; i < SIZE; i++) {
            error[i] = dataSeriesX[i] - dataSeriesY[i];
            dif[i] = error[i] * error[i];
            sum += dif[i];
            printToFile("MSE", "Frequency: " + frequencies[i] + " X : " + dataSeriesX[i] + " Y: " + dataSeriesY[i] + " error:" + dif[i]);
        }

        double MSE = sum / (SIZE);
        System.out.println("Mean Squared Error is: " + MSE);
    }

    /**Print the info to the log file*/
    public void printToFile(String name, String input) {
        try {
            FileWriter write = new FileWriter(name + ".txt", true);
            PrintWriter text = new PrintWriter(write);
            text.println(input);
            text.flush();
            write.close();

        } catch (Exception e) {
            System.err.println("Error: " + e.getMessage());
        }
    }
}
